<template>
  <div class="msg-list">
    <van-list v-if="currentList.length > 0">
      <van-swipe-cell v-for="(item, index) in currentList" :key="item.id">
        <div class="list-item">
          <div @click="handleItemClick(item)">
            <div v-if="selectMode" class="checkbox">
              <van-checkbox shape="square" :checked="selectedIds.includes(item.id)" />
            </div>
            <div class="avatar">
              <van-badge :dot="activeTab === 'in-box' && item.readStatus === 0" :offset="[-6, 6]">
                <img :class="getIconClass(item.sender, index)" />
              </van-badge>
            </div>
            <div class="msg">
              <div class="from">
                <span>{{ item.sender }}</span>
                <span>{{ dateFormat(item.sendTime) }}</span>
              </div>
              <div class="title">{{ item.messageSubject }}</div>
              <div class="content">{{ handleMsgContent(item.content) }}</div>
            </div>
          </div>
        </div>
        <template #right>
          <van-button
            v-if="activeTab === 'in-box' && item.readStatus === 0"
            square
            type="primary"
            text="已读"
            @click="updateStatusById(item.id)"
          />
          <van-button square type="danger" text="删除" @click="deleteById(item.id)" />
        </template>
      </van-swipe-cell>
    </van-list>
    <van-empty v-else description="暂无数据" />
    <div v-if="selectMode">
      <div class="operation-bar-placeholder"></div>
      <div class="operation-bar">
        <template v-if="selectedIds.length > 0">
          <div v-if="activeTab === 'in-box'" class="operation-read" @click="updateStatusByIds">
            <div>
              <img src="@/assets/msg/icon-read.svg" />
            </div>
            <div>已读</div>
          </div>
          <div class="operation-delete" @click="deleteByIds">
            <div>
              <img src="@/assets/msg/icon-delete.svg" />
            </div>
            <div>删除</div>
          </div>
        </template>
        <template v-else>
          <div v-if="activeTab === 'in-box'" class="operation-read-disabled">
            <div>
              <img src="@/assets/msg/icon-read-disable.svg" />
            </div>
            <div>已读</div>
          </div>
          <div class="operation-delete-disabled">
            <div>
              <img src="@/assets/msg/icon-delete-disable.svg" />
            </div>
            <div>删除</div>
          </div>
        </template>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { showConfirmDialog, showToast } from 'vant'
import { ref, watch, computed } from 'vue'
import { useRouter } from 'vue-router'
import dayjs from 'dayjs'
import { storeToRefs } from 'pinia'
import { useMsgStore } from '@/store'
import MsgServe from '@/api/msg'
import type { MsgItem } from '@/store/type'

defineOptions({
  name: 'MsgList'
})

const emit = defineEmits(['switch', 'refresh'])
const router = useRouter()

// 父组件传参
interface IProps {
  selectMode: boolean
  activeTab: string
}
const props = withDefaults(defineProps<IProps>(), {
  selectMode: false,
  activeTab: ''
})

// 将消息文本从HTML中提取出来
const handleMsgContent = (content: string) => {
  return content.replace(/<[^<>]+>/g, '')
}

// 多选模式监听
watch(
  () => props.selectMode,
  newValue => {
    // 开启多选模式后清空选项
    if (newValue) {
      selectedIds.value = []
    }
  }
)

// 当前消息列表
const msgStore = useMsgStore()
const { receiveList, sendList } = storeToRefs(msgStore)
const currentList = computed(() => {
  if (props.activeTab === 'outbox') {
    return sendList.value
  }
  return receiveList.value
})

// 当前消息列表监听
watch(
  () => currentList.value,
  () => {
    // 消息列表发生变化时清空选项，并退出多选模式
    selectedIds.value = []
    emit('switch', false)
  }
)

// 标记已读
const updateStatusById = (id: number) => {
  MsgServe.updateSendStatus({ ids: id })
    .then(res => {
      showToast('标记已读成功')
      emit('refresh')
    })
    .catch(error => {
      showToast('标记已读失败，请稍后再试')
      console.error('标记已读失败：', error)
    })
}

// 删除消息
const deleteById = (id: number) => {
  MsgServe.deleteMessage({ ids: id })
    .then(res => {
      showToast('删除消息成功')
      emit('refresh')
    })
    .catch(error => {
      showToast('删除消息失败，请稍后再试')
      console.error('删除消息失败：', error)
    })
}

// 多选标记为已读
const updateStatusByIds = () => {
  if (selectedIds.value.length > 0) {
    showConfirmDialog({
      title: '提示',
      message: '确定要将已选的消息标记为已读吗？',
      beforeClose: (action: string) =>
        new Promise(resolve => {
          if (action === 'confirm') {
            MsgServe.updateSendStatus({ ids: selectedIds.value.join(',') }).then(res => {
              showToast('标记已读成功')
              emit('refresh')
            }).catch(error => {
              showToast('标记已读失败，请稍后再试')
              console.error('标记已读失败：', error)
            }).finally(() => {
              resolve(true)
            })
          } else {
            resolve(true)
          }
        })
    })
  }
}

// 多选删除
const deleteByIds = () => {
  if (selectedIds.value.length > 0) {
    showConfirmDialog({
      title: '提示',
      message: '确定要删除已选的消息吗？',
      beforeClose: (action: string) =>
        new Promise(resolve => {
          if (action === 'confirm') {
            MsgServe.deleteMessage({ ids: selectedIds.value.join(',') }).then(res => {
              showToast('删除消息成功')
              emit('refresh')
            }).catch(error => {
              showToast('删除消息失败，请稍后再试')
              console.error('删除消息失败：', error)
            }).finally(() => {
              resolve(true)
            })
          } else {
            resolve(true)
          }
        })
    })
  }
}

// 点击列表项
const handleItemClick = (msgItem: MsgItem) => {
  if (props.selectMode) {
    // 多选模式时默认选择操作
    handleSelectChange(msgItem.id)
  } else {
    // 跳转到消息详情
    msgStore.setCurrentItem(msgItem)
    router.push('/msgContent/' + msgItem.id)
  }
}

// 多选相关
const selectedIds = ref<number[]>([])
const handleSelectChange = (id: number) => {
  const checked = selectedIds.value.includes(id)
  if (checked) {
    selectedIds.value = selectedIds.value.filter(item => item !== id)
  } else {
    selectedIds.value.push(id)
  }
}

// 图标相关
interface IIconMap {
  [key: string]: string
}
const iconMap: IIconMap = {
  系统: 'icon-system',
  指挥中心: 'icon-zhihuizhongxin',
  场景: 'icon-changjing'
}
const getIconClass = (from: string, index: number) => {
  // 根据发件人或者下标获取对应图标
  const className = iconMap[from]
  return className || `icon-default-${(index % 4) + 1}`
}

// 优化收件日期展示
const dateFormat = (dateTime: string) => {
  const dateObj = dayjs(dateTime, 'YYYY-MM-DD HH:mm:ss')
  // 今天
  if (dayjs().format('YYYY-MM-DD') === dateObj.format('YYYY-MM-DD')) {
    return dateObj.format('HH:mm')
  } else if (dayjs().subtract(1, 'days').format('YYYY-MM-DD') === dateObj.format('YYYY-MM-DD')) {
    return dateObj.format('昨天HH:mm')
  }
  return dateObj.format('YYYY-MM-DD HH:mm')
}
</script>

<style lang="less" scoped>
.msg-list {
  position: relative;
  .list-item {
    padding: 0 16px;
    &:active {
      background-color: rgba(0, 0, 0, 0.1);
    }
    > div {
      padding: 16px 0;
      display: flex;
      border-bottom: 1px solid #e2e2e2;
      .checkbox {
        margin-right: 12px;
        display: flex;
        align-items: center;
      }
      .avatar {
        display: flex;
        align-items: center;
        img {
          width: 42.95px;
          height: 42.95px;
        }
        img.icon-system {
          content: url('@/assets/msg/icon-system.svg');
        }
        img.icon-zhihuizhongxin {
          content: url('@/assets/msg/icon-zhihuizhongxin.svg');
        }
        img.icon-changjing {
          content: url('@/assets/msg/icon-changjing.svg');
        }
        img.icon-default-1 {
          content: url('@/assets/msg/icon-default-1.svg');
        }
        img.icon-default-2 {
          content: url('@/assets/msg/icon-default-2.svg');
        }
        img.icon-default-3 {
          content: url('@/assets/msg/icon-default-3.svg');
        }
        img.icon-default-4 {
          content: url('@/assets/msg/icon-default-4.svg');
        }
      }
      .msg {
        flex: 1;
        margin-left: 12px;
        .from {
          display: flex;
          justify-content: space-between;
          > span:nth-child(1) {
            font-weight: 500;
            color: #4389f3;
            font-size: 11.54px;
          }
          > span:nth-child(2) {
            font-weight: 300;
            color: #444444;
            font-size: 8.97px;
          }
        }
        .title {
          font-weight: 500;
          color: #333333;
          font-size: 13.46px;
          margin-top: 4px;
        }
        .content {
          font-weight: 500;
          color: #666666;
          font-size: 9.62px;
          margin-top: 4px;
          display: -webkit-box;
          text-overflow: ellipsis;
          overflow: hidden;
          -webkit-line-clamp: 1;
          -webkit-box-orient: vertical;
        }
      }
    }
  }
  :deep(.van-badge.van-badge--dot) {
    width: 11.54px;
    height: 11.54px;
    background: #ff5723;
  }
  .van-button {
    height: 100%;
    &.van-button--primary {
      background-color: #4389f3;
      border-color: #4389f3;
      font-size: 13.46px;
    }
    &.van-button--danger {
      background-color: #ff5723;
      border-color: #ff5723;
      font-size: 13.46px;
    }
  }
  .operation-bar-placeholder,
  .operation-bar {
    height: 50px;
  }
  .operation-bar-placeholder {
    width: 100%;
  }
  .operation-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: white;
    border-top: 1px solid #e2e2e2;
    display: flex;
    align-items: center;
    justify-content: center;
    > div {
      > div:nth-child(1) {
        img {
          width: 23.08px;
          height: 23.08px;
        }
      }
      > div:nth-child(2) {
        text-align: center;
        font-size: 9.94px;
      }
    }
    > div:not(:first-child) {
      margin-left: 64px;
    }
    .operation-read {
      color: #4389f3;
    }
    .operation-delete {
      color: #ff5723;
    }
    .operation-read-disabled,
    .operation-delete-disabled {
      color: #666666;
    }
  }
}
</style>
